package com.eagle.nenaboot.server.core.handler;


import com.eagle.nenaboot.common.protocol.ConnectPacket;
import com.eagle.nenaboot.common.protocol.DataPacket;
import com.eagle.nenaboot.common.utils.SessionUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;


import java.net.InetSocketAddress;

//import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 *  客户端入口拦截器
 * <p>
 *
 * @author eagle liu
 * @since 2020/3/13 21:14
 */
@Slf4j
public class ProxyHandler extends ChannelInboundHandlerAdapter {


    public ProxyHandler() {}

	/**
	 * 当客户端有80的请求时候，会触发这里
	 * 比如 <域名/IP>:80/test
	 * @param ctx
	 * @throws Exception
	 */
	@Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        ConnectPacket connectPacket = new ConnectPacket();
        connectPacket.setChannelId(ctx.channel().id().asLongText());
        InetSocketAddress address = (InetSocketAddress)ctx.channel().localAddress();
        String hostName = address.getHostName();
        log.info("第五步， 连接进来。host 为：[{}]，并向10240的channel写入connectPacket", hostName);
        if(StringUtils.isNotEmpty(hostName)){

            String token = SessionUtil.getToken();
            // 获取对应连接的客户端channel
			//注意：这个channel是10240的channel.不是80自己的
            Channel channel = SessionUtil.getChannel(token);
            if(channel == null){
				System.out.println("host ：[{}], 绑定的客户端没有连接成功"+ hostName);
//                log.warn("host ：[{}], 绑定的客户端没有连接成功", hostName);
                return;
            }
            SessionUtil.bindChannel(connectPacket.getChannelId(), ctx.channel());

            channel.writeAndFlush(connectPacket);
        }
    }

    /**
	 * 第九步，之前访问者已经拿到访问的数据（上面channelActive触发），这个时候访问者请求数据过来，
	 * 要跟新本地服务，就10240客户端口发送DataPacket
     * <p
     *  处理请求入口、并且通过请求的域名找到相关代理的channel
     * <p>
     *
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception{
		log.info("第九步，访问者数据完毕后，这个时候访问者请求数据过来要跟新本地服务，" +
				"就10240客户端口发送DataPacket");
        byte[] data = (byte[]) msg;
        InetSocketAddress address = (InetSocketAddress)ctx.channel().localAddress();
        String hostName = address.getHostName();
        if(StringUtils.isNotEmpty(hostName)){
            String token = SessionUtil.getToken();
            // 获取对应连接的客户端channel
            Channel channel = SessionUtil.getChannel(token);
            if(channel == null){
                log.warn("host ：[{}], 绑定的客户端没有连接成功", hostName);
                return;
            }
            DataPacket dataPacket = new DataPacket();
            dataPacket.setToken(token);
            dataPacket.setBytes(data);
            dataPacket.setChannelId(ctx.channel().id().asLongText());
            SessionUtil.bindChannel(ctx.channel().id().asLongText(), ctx.channel());
            channel.writeAndFlush(dataPacket);
        }
    }


    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        SessionUtil.unBindChannel(ctx.channel().id().asLongText());
		log.info("channelId:{},链接关闭", ctx.channel().id().asLongText());
    }
}
